<script setup name="adm">
import { ref, shallowRef, toRaw, onMounted } from 'vue';
import { useRouter } from 'vue-router';

import { ElTable, ElTableColumn, ElPagination, ElSelect, ElOption, ElDialog, ElMessage } from 'element-plus';
import { Search, Plus, Document } from '@element-plus/icons-vue';
import service from '@/utils/request';

const router = useRouter();
const importHeaders = {
  Authorization: 'Bearer ' + localStorage.getItem('token'),
};

// 表格数据相关
const tableData = ref([]);
const pageNum = shallowRef(1);
const pageSize = shallowRef(5);
const totalSize = shallowRef(0);
const selectable = (row) => row.state === "启用";

// 搜索框相关
const searchValue = shallowRef('');
const searchRef = shallowRef(null);

// 对话框显示相关
const isShowAddAdm = ref(false);
const isShowImport = ref(false);
const isShowResetPassword = ref(false);

// 新建管理员对话框数据
const addAdmData = ref({
  name: '',
  jobId: '',
  department: '',
  password: '',
});

// 重置密码对话框数据
const resetPasswordData = ref({
  id: '',
  password: '',
});

// 批量导出的数据
const selectedExportData = ref([]);

const newPassword = shallowRef('');
const errObj = ref({
  oldPasswordErr: "",
  newPasswordErr: "",
  confirmPasswordErr: "",
});

const newPasswordInput = () => {
  if (newPassword.value === '') {
    errObj.value.newPasswordErr = '新密码不能为空';
    return;
  }
  errObj.value.newPasswordErr = '';
}

const confirmPasswordInput = (event) => {
  if(event.target.value === '') {
    errObj.value.confirmPasswordErr = '确认密码不能为空';
    return;
  }
  if(event.target.value !== newPassword.value) {
    errObj.value.confirmPasswordErr = '两次输入的密码不一致';
    return;
  }
  errObj.value.confirmPasswordErr = '';
}

// 重置密码的保存方法
const resetPasswordSaveClick = (data) => {
  if(data == '') {
    ElMessage({
      message: '请输入新密码',
      type: 'error',
    });
    return;
  }
  for (let k in errObj.value) {
    if (errObj.value[k] !== '') {
      ElMessage({
        message: errObj.value[k],
        type: 'error',
      });
      return;
    }
  }
  service({
    method: "post",
    url: "/superadmin/admin/reset",
    headers: {
      Authorization: 'Bearer ' + localStorage.getItem('token'),
    },
    data: {
      id: resetPasswordData.value.id,
      password: data
    }
  }).then((res) => {
    if (res.message == '请求正常') {
      ElMessage({
        message: '重置成功',
        type: 'success',
      });
      isShowResetPassword.value = false;
      // 重置密码输入框
      newPassword.value = '';
      errObj.value = {
        oldPasswordErr: "",
        newPasswordErr: "",
        confirmPasswordErr: "",
      };
    } else {
      ElMessage({
        message: '重置失败',
        type: 'error',
      });
    }
  });
};

// 处理表格数据
const fixedTableData = (list) => {
  if (!list) return [];
  return list.map((item) => ({
    name: item.username,
    jobId: item.id,
    department: item.school,
    state: item.state,
    operation: {
      resetPassword: "重置密码",
      edit: "编辑",
      changeState: item.state === "启用" ? "停用" : "启用"
    },
  }));
};

// 获取表格数据
const getTableData = (searchKey) => {
  service({
    method: "get",
    url: "/superadmin/admin/select",
    headers: {
      Authorization: 'Bearer ' + localStorage.getItem('token'),
    },
    params: {
      condition: searchKey,
      pageNum: pageNum.value,
      pageSize: pageSize.value
    }
  }).then((res) => {
    tableData.value = fixedTableData(res.data.list);
    totalSize.value = res.data.total || 0;
  }).catch((error) => {
    ElMessage({
      message: '获取数据失败',
      type: 'error',
    });
    tableData.value = [];
    totalSize.value = 0;
  });
};

// 搜索相关事件
const searchChange = () => getTableData(searchValue.value);

// 新建管理员
const addAdmClick = () => {
  for (let k in addAdmData.value) {
    if (addAdmData.value[k] === '') {
      ElMessage({
        message: '请填写完整信息',
        type: 'warning',
      });
      return;
    }
  }
  service({
    method: "post",
    url: "/superadmin/admin/add",
    headers: {
      Authorization: 'Bearer ' + localStorage.getItem('token'),
    },
    data: {
      name: addAdmData.value.name,
      id: addAdmData.value.jobId,
      school: addAdmData.value.department,
      password: addAdmData.value.password
    }
  }).then((res) => {
    if (res.data.success) {
      isShowAddAdm.value = false;
      Object.keys(addAdmData.value).forEach(key => addAdmData.value[key] = '');
      ElMessage({
        message: '添加成功',
        type: 'success',
      });
      getTableData(searchValue.value);
    } else {
      ElMessage({
        message: '添加失败 ' + res.data.errors[0].errorMessage,
        type: 'error',
      });
    }
  });
};

const cancelAdmClick = () => {
  isShowAddAdm.value = false;
  Object.keys(addAdmData.value).forEach(key => addAdmData.value[key] = '');
};

// 批量导入文件相关
const downloadModelClick = () => {
  const elink = document.createElement('a');
  elink.download = '批量导入管理员模板.xlsx';
  elink.style.display = 'none';
  elink.href = "https://qzy-1342857676.cos.ap-guangzhou.myqcloud.com/批量导入管理员模板.xlsx";
  document.body.appendChild(elink);
  elink.click();
  document.body.removeChild(elink);
};

const fileImportSuccess = (res) => {
  if (res.data.success) {
    ElMessage({
      message: '导入成功',
      type: 'success',
    });
    getTableData('');
    isShowImport.value = false;
  } else {
    ElMessage({
      message: '导入失败 ' + res.data.errors[0].errorMessage,
      type: 'error',
    });
  }
};

const fileImportError = () => {
  ElMessage({
    message: '导入失败',
    type: 'error',
  });
};

// 批量导出相关
const selectionChange = (data) => {
  selectedExportData.value = data.map((item) => item.jobId);
};

const exportClick = () => {
  if (selectedExportData.value.length === 0) {
    ElMessage({
      message: '请选择成员',
      type: 'warning',
    });
    return;
  }
  service({
    method: "post",
    url: "/superadmin/admin/export",
    headers: {
      Authorization: 'Bearer ' + localStorage.getItem('token'),
    },
    data: toRaw(selectedExportData.value),
    responseType: 'blob'
  }).then((res) => {
    const blob = new Blob([res.data]);
    const fileName = '管理员导出.xlsx';
    const elink = document.createElement('a');
    elink.download = fileName;
    elink.style.display = 'none';
    elink.href = URL.createObjectURL(blob);
    document.body.appendChild(elink);
    elink.click();
    document.body.removeChild(elink);
    ElMessage({
      message: '导出成功',
      type: 'success',
    });
  }).catch((error) => {
    ElMessage({
      message: '导出失败',
      type: 'error',
    });
  });
};

// 表格操作相关
const resetPasswordClick = (row) => {
  isShowResetPassword.value = true;
  resetPasswordData.value.id = row.id;
};

const editClick = (row) => {
  router.push({
    path: '/superAdministrator/adm/admEdit',
    query: row
  });
};

const changeStateClick = (id, name) => {
  service({
    method: "get",
    url: "/superadmin/admin/change",
    headers: {
      Authorization: 'Bearer ' + localStorage.getItem('token'),
    },
    params: { id }
  }).then((res) => {
    if (res.message == '请求正常') {
      ElMessage({
        message: `修改${name}状态成功`,
        type: 'success',
      });
      getTableData(searchValue.value);
    } else {
      ElMessage({
        message: '修改失败',
        type: 'error',
      });
    }
  });
};

// 分页器相关事件
const handleSizeChange = (data) => {
  pageNum.value = data;
  getTableData(searchValue.value);
};

onMounted(() => {
  getTableData('');
});
</script>

<template>
  <!-- 重置密码对话框 -->
  <div class="resetPassword">
    <el-dialog 
      draggable
      :model-value="isShowResetPassword" 
      width="40%" 
      top="30vh"
      :show-close="false"
      :open-delay="100"
      :close-on-click-modal="false"
    >
      <!-- 标题部分 -->
      <template #header>
        <div class="dialogTitle">
          <div class="line"></div>
          <div>重置密码</div>
        </div>
      </template>
      <!-- 内容部分 -->
      <template #default>
        <div class="dialogContent">
          <div class="newPassword">
            <div class="title">
              <span>新密码：</span>
            </div>
            <div class="inputPart">
              <input 
                type="text" 
                v-model="newPassword"
                @keyup.enter="newPasswordInput"
                @blur="newPasswordInput"
              >
              <div class="err">{{ errObj.newPasswordErr }}</div>
            </div>
          </div>
          <div class="confirmPassword">
            <div class="title">
              <span>确认密码：</span>
            </div>
            <div class="inputPart">
              <input 
                type="text"
                @keyup.enter="confirmPasswordInput"
                @blur="confirmPasswordInput"
              >
              <div class="err">{{ errObj.confirmPasswordErr }}</div>
            </div>
          </div>
          <div class="footer">
            <div class="save" @click="resetPasswordSaveClick(newPassword)">保存</div>
            <div class="cancel" @click="isShowResetPassword = false">取消</div>
          </div>
        </div>
      </template>
    </el-dialog>        
  </div>
  
  <!-- 批量导入对话框 -->
  <el-dialog
    draggable
    :model-value="isShowImport"
    width="50%"
    top="20vh"
    @close="isShowImport = false"
    class="import-dialog"
  >
    <template #header>
      <div class="importHeader">批量导入</div>
    </template>
    <template #default>
      <div class="importContent">
        <div class="item">
          <span>下载模板</span>
          <el-icon size="100"><Document /></el-icon>
          <span class="downloadBtn" @click="downloadModelClick">
            <span>下载</span>
            <span class="iconfont icon-daoru"></span>                          
          </span>
        </div>
        <div class="item">
          <span>导入文件</span>
          <el-icon size="100"><Document /></el-icon>
          <el-upload
            :headers="importHeaders"
            action="http://192.168.116.86:8080/superadmin/admin/upload"
            :on-success="fileImportSuccess"
            :on-error="fileImportError"
            :show-file-list="false"
          >
            <span class="importBtn">导入</span>
          </el-upload>
        </div>
      </div>
    </template>
  </el-dialog>
  
  <!-- 新建管理员对话框 -->
  <el-dialog 
    :model-value="isShowAddAdm" 
    width="40%" 
    top="15vh" 
    destroy-on-close
    :close-on-click-modal="false"
    :show-close="false"
    draggable
    class="create-adm-dialog"
  >
    <template #header>
      <div class="createAdmHeader">新建管理员信息</div>
    </template>
    <template #default>
      <div class="createAdmContent">
        <div class="item">
          <span class="title">姓名</span>
          <input type="text" placeholder="请输入" v-model="addAdmData.name" class="form-input">
        </div>
        <div class="item">
          <span class="title">工号</span>
          <input type="text" placeholder="请输入" v-model="addAdmData.jobId" class="form-input">
        </div>
        <div class="item">
          <span class="title">学院</span>
          <input type="text" placeholder="请输入" v-model="addAdmData.department" class="form-input">
        </div>
        <div class="item">
          <span class="title">初始密码</span>
          <input type="text" placeholder="请输入" v-model="addAdmData.password" class="form-input">
        </div>
      </div>
    </template>
    <template #footer>
      <div class="createAdmFooter">
        <div class="cancel-btn" @click="cancelAdmClick">取消</div>
        <div class="submit-btn" @click="addAdmClick">添加</div>
      </div>
    </template>
  </el-dialog>
  
  <!-- 管理员管理内容 -->
  <div class="adm">
    <div class="header">
      <span>管理员管理</span>
    </div>
    <div class="content">
      <div class="dataTable">
        <!-- 搜索框和操作按钮头部 -->
        <div class="tableHeader">
          <div class="left">
            <span>管理员管理</span>
          </div>
          <div class="right">
            <div class="search" ref="searchRef">
              <input 
                v-model.trim="searchValue" 
                type="text" 
                placeholder="搜索" 
                @change.enter="searchChange"
              />
              <el-icon class="icon"><Search /></el-icon> 
            </div>
            <div class="createAdm" @click="isShowAddAdm = true">
              <span>新建管理员</span>
              <el-icon><Plus /></el-icon>
            </div>
            <div class="importAdm" @click="isShowImport = true">
              <span>批量导入</span>
              <span class="iconfont icon-daoru"></span>
            </div>
            <div class="exportAdm" @click="exportClick">
              <span>批量导出</span>
              <span class="iconfont icon-export"></span>
            </div>
          </div>
        </div>
        
        <!-- 数据表格 -->
        <div class="tableContent">
          <el-table 
            :data="tableData"
            row-key="jobId"
            :style="{ width: '100%' }"
            height="100%"
            show-overflow-tooltip
            empty-text="暂无数据"
            :header-cell-style="{ color: '#000', background: '#f2f3f5' }"
            @selection-change="selectionChange"
          >
            <el-table-column type="selection" width="55" :selectable="selectable" />
            <el-table-column align="left" prop="name" label="姓名" width="150" />
            <el-table-column align="center" prop="jobId" label="工号" width="150" />
            <el-table-column align="left" prop="department" label="学院" />
            <el-table-column align="center" prop="state" label="状态" width="150">
              <template #default="scope">
                <span :class="`state-${scope.row.state}`">{{ scope.row.state }}</span>
              </template>
            </el-table-column>
            <el-table-column align="center" prop="operation" label="操作" width="200" fixed="right">
              <template #default="scope">
                <span class="operation-link" @click="resetPasswordClick(scope.row)">{{ scope.row.operation.resetPassword }}</span>
                <span style="color:#e5e6eb;padding: 0 3px;">|</span>
                <span class="operation-link" @click="editClick(scope.row)">{{ scope.row.operation.edit }}</span>
                <span style="color:#e5e6eb;padding: 0 3px;">|</span>
                <span class="operation-link" @click="changeStateClick(scope.row.jobId, scope.row.name)">{{ scope.row.operation.changeState }}</span>
              </template>
            </el-table-column>
          </el-table>
        </div>
        
        <!-- 底部分页器 -->
        <div class="tableFooter">
          <div class="left">
            <div class="total">共计: {{ totalSize }} 条</div>
          </div>
          <div class="right">
            <div class="pagination">
              <el-pagination
                layout="prev, pager, next"
                :total="totalSize"
                :page-size="pageSize"
                background
                size="small"
                @current-change="handleSizeChange"
              />
            </div>
            <div class="selector">
              <el-select 
                v-model="pageSize" 
                placeholder="每页条数" 
                style="width: 80px;"
                size="small"
                @change="getTableData(searchValue)"
              >
                <el-option label="5条/页" :value="5" selected />
                <el-option label="10条/页" :value="10" />
                <el-option label="20条/页" :value="20" />
              </el-select>
            </div>
            <div class="jump">
              <span class="title">前往:</span>
              <input type="text" v-model="pageNum" @change="getTableData(searchValue)" />
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<style scoped lang="scss">
@use "sass:color";

// 颜色变量
$primary-color: #4c6fb4;
$danger-color: #eb5757;
$danger-hover: #ff6b6b;
$gray-color: #909399;
$gray-hover: #a0a2a5;
$bg-light: #f1f2f3;
$bg-lighter: #f2f3f5;
$border-color: #cacacb;
$text-primary: #000000;
$text-secondary: #86909c;
$text-tertiary: #8e96a0;
$success-color: #00af1d;
$inactive-color: #898989;
$enable-color: #96ce71;
$disable-color: #eb5757;

// 导入字体图标
@use "./fonticon/commonFonticon/iconfont.css";

// 重置密码对话框样式
.dialogTitle{
  display: flex;
  align-items: center;
  gap: 5px;
  font-size: 20px;
  font-weight: 500;
  .line{
    width: 4px;
    height:20px;
    border-radius: 2px;
    background-color: #2d5cf6;
  }
}
.dialogContent{
  margin-top: 30px;
  width: 100%;
  padding-left: 5px;
  display: flex;
  flex-direction: column;
  gap: 40px;
  font-weight: 500;
  .newPassword, .confirmPassword{
    width: 100%;
    display: flex;
    align-items: center;
    .title{
      font-size: 16px;
      width: 90px;
      &::before{
        content: '*';
        color: red;
      }            
    }
    .inputPart{
      position: relative;
      input{
        width: 15vw;
        height: 3.5vh;
        border: none;
        border-radius: 5px;
        background-color: #f2f3f5;
        text-indent: 5px;
        transition: all 0.3s ease;
        &:focus{
          outline: 2px solid #4c6fb4;
          box-shadow: 0 0 5px rgba(76, 109, 180, 0.5);
        }
      }
      .err{
        position: absolute;
        top: 3.5vh;
        left: 0;
        font-size: 10px;
        color: red;
      }
    }
  }
  .footer{
    width: 100%;
    margin-top: 10px;
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap:20px;
    font-weight: 400;
    font-size: 15px;
    .save{
      width: 5vw;
      height: 3.5vh;
      border-radius: 5px;
      background-color: #4c6fb4;
      text-align: center;
      line-height: 3.5vh;
      color:white;
      &:hover{
        background-color: color.adjust($primary-color, $lightness: -5%);
      }
    }
    .cancel{
      width: 5vw;
      height: 3.5vh;
      border-radius: 5px;
      background-color: #f2f3f5;
      text-align: center;
      line-height: 3.5vh;
      color: $text-primary;
      &:hover{
        background-color: color.adjust($bg-lighter, $lightness: -5%);
      }
    }
  }
}

// 批量导入对话框
.import-dialog {
  .el-dialog__body {
    padding: 30px;
  }
}

.importHeader {
  font-size: 20px;
  font-weight: 600;
  color: $text-primary;
}

.importContent {
  margin: 50px 0;
  display: flex;
  justify-content: space-between;
  font-size: 18px;
  
  .item {
    width: 50%;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 30px;
    
    .downloadBtn {
      width: 100px;
      height: 30px;
      display: flex;
      align-items: center;
      justify-content: center;
      gap: 10px;
      border: 2px solid $primary-color;
      border-radius: 10px;
      color: $primary-color;
      cursor: pointer;
      font-size: 16px;
      font-weight: 500;
      transition: all 0.3s ease;
      
      &:hover {
        background-color: $primary-color;
        color: white;
      }
    }
    
    .importBtn {
      width: 70px;
      height: 30px;
      border-radius: 10px;
      background-color: $primary-color;
      color: white;
      text-align: center;
      line-height: 30px;
      cursor: pointer;
      font-size: 16px;
      transition: all 0.3s ease;
      
      &:hover {
        background-color: color.adjust($primary-color, $lightness: -5%);
      }
    }
  }
}

// 创建管理员对话框
.create-adm-dialog {
  .el-dialog__body {
    padding: 30px;
  }
}

.createAdmHeader {
  font-size: 20px;
  font-weight: 600;
  color: $text-primary;
}

.createAdmContent {
  width: 100%;
  .item {
    width: 100%;
    margin-bottom: 24px;
    display: flex;
    align-items: center;
    gap: 20px;
    
    .title {
      width: 70px;
      text-align: right;
      font-size: 14px;
      font-weight: 500;
      color: $text-primary;
      position: relative;
      padding-right: 10px;
      
      &::after {
        content: "*";
        position: absolute;
        right: 0;
        color: $danger-color;
      }
    }
    
    .form-input {
      width: calc(60% - 70px);
      height: 40px;
      border: 1px solid $border-color;
      border-radius: 6px;
      padding: 0 12px;
      font-size: 14px;
      color: $text-primary;
      background-color: #fff;
      transition: all 0.3s ease;
      
      &:focus {
        outline: none;
        border-color: $primary-color;
        box-shadow: 0 0 0 1px color.adjust($primary-color, $alpha: 0.1);
      }
      
      &::placeholder {
        color: $text-tertiary;
      }
    }
  }
}

.createAdmFooter {
  display: flex;
  justify-content: flex-end;
  gap: 12px;
  padding: 16px 0;
  .cancel-btn,
  .submit-btn {
    padding: 8px 20px;
    border-radius: 6px;
    font-size: 14px;
    font-weight: 500;
    cursor: pointer;
    transition: all 0.3s ease;
    
    &:active {
      transform: scale(0.98);
    }
  }
  
  .cancel-btn {
    background-color: #f5f7fa;
    color: $text-secondary;
    border: 1px solid $border-color;
    
    &:hover {
      background-color: #eef2f7;
      color: $text-primary;
    }
  }
  
  .submit-btn {
    background-color: $primary-color;
    color: white;
    
    &:hover {
      background-color: color.adjust($primary-color, $lightness: -5%);
      box-shadow: 0 2px 8px color.adjust($primary-color, $alpha: 0.3);
    }
  }
}

// 管理员管理组件内容
.adm {
  width: 100%;
  height: 100%;
  font-weight: 500;
  .header {
    width: 100%;
    height: 60px;
    padding-left: 20px;
    display: flex;
    align-items: center;
    border-top: 1px solid $border-color;
    border-bottom: 1px solid $border-color;
    background-color: white;
    font-size: 23px;
    color: $text-primary;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
  }
  
  .content {
    width: 100%;
    height: calc(100% - 60px);
    display: flex;
    justify-content: center;
    align-items: center;
    padding: 20px;
    background-color: #f7f8fa;
    
    .dataTable {
      width: 100%;
      height: 100%;
      background-color: #ffffff;
      border-radius: 8px;
      box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
      overflow: hidden;
      
      .tableHeader {
        width: 100%;
        height: 10%;
        padding: 0 20px;
        display: flex;
        align-items: center;
        justify-content: space-between;
        border-bottom: 1px solid #f0f0f0;
        
        .left {
          width: 200px;
          font-size: 20px;
          font-weight: 600;
          color: $text-primary;
        }
        
        .right {
          width: calc(100% - 200px);
          display: flex;
          justify-content: flex-end;
          align-items: center;
          gap: 15px;
          
          .search {
            width: 20vw;
            height: 4vh;
            display: flex;
            align-items: center;
            border-radius: 6px;
            background-color: $bg-light;
            transition: all 0.3s ease;
            
            &:hover {
              background-color: #e0e1e2;
            }
            
            &:focus-within {
              outline: 2px solid $primary-color;
              background-color: #ffffff !important;
              box-shadow: 0 0 0 3px rgba($primary-color, 0.1);
            }
            
            input {
              height: 100%;
              width: 90%;
              outline: none;
              border: none;
              background-color: transparent;
              text-indent: 1em;
              color: $text-primary;
            }
            
            .icon {
              width: 10%;
              height: 100%;
              display: flex;
              align-items: center;
              justify-content: center;
              cursor: pointer;
              color: $text-tertiary;
              
              &:hover {
                color: $primary-color;
              }
            }
          }
          
          .createAdm,
          .importAdm,
          .exportAdm {
            display: flex;
            align-items: center;
            justify-content: center;
            gap: 6px;
            padding: 0 16px;
            height: 36px;
            border-radius: 6px;
            font-size: 14px;
            font-weight: 500;
            cursor: pointer;
            transition: all 0.3s ease;
            &:active {
              transform: scale(0.98);
            }
          }
          
          .createAdm {
            background-color: $primary-color;
            color: white;
            &:hover {
              background-color: color.adjust($primary-color, $lightness: -5%);
              box-shadow: 0 2px 8px color.adjust($primary-color, $alpha: 0.3);
            }
          }
          
          .importAdm,
          .exportAdm {
            border: 1px solid $primary-color;
            color: $primary-color;
            background-color: white;
            
            &:hover {
              color: white;
              background-color: color.adjust($primary-color, $alpha: 0.05);
              border-color: color.adjust($primary-color, $lightness: -5%);
            }
          }
        }
      }
      
      .tableContent {
        width: 100%;
        height: 80%;
        padding: 0 20px;
        
        .state-启用 {
          color: $enable-color;
        }
        
        .state-禁用 {
          color: $disable-color;
        }
        
        .operation-link {
          color: $primary-color;
          cursor: pointer;
          transition: all 0.3s ease;
          
          &:hover {
            color: #2c6df9;
            text-decoration: underline;
          }
        }
      }
      
      .tableFooter {
        width: 100%;
        height: 10%;
        padding: 0 20px;
        display: flex;
        align-items: center;
        justify-content: space-between;
        border-top: 1px solid #f0f0f0;
        
        .left {
          font-size: 12px;
          color: $text-secondary;
        }
        
        .right {
          display: flex;
          align-items: center;
          gap: 15px;
          
          .jump {
            display: flex;
            align-items: center;
            
            .title {
              margin-right: 5px;
              font-size: 12px;
              color: $text-secondary;
            }
            
            input {
              width: 40px;
              height: 28px;
              text-align: center;
              line-height: 28px;
              border: 1px solid #dcdfe6;
              outline: none;
              border-radius: 4px;
              background-color: #ffffff;
              color: $text-secondary;
              transition: all 0.3s ease;
              
              &:focus {
                border-color: $primary-color;
                color: $text-primary;
                box-shadow: 0 0 0 2px color.adjust($primary-color, $alpha: 0.1);
              }
            }
          }
        }
      }
    }
  }
}
</style>